<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
    <title>NFA Map</title>
    <style>
        svg {
            border: 1px solid #999;
            overflow: hidden;
        }

        .node circle {
            stroke: #333;
            fill: #fff;
            stroke-width: 2px;
        }

        .edgePath path {
            stroke: #333;
            fill: #333;
            stroke-width: 2px;
        }
    </style>
    <style>
        html {
            height: 80%;
            margin: 0;
        }

        body {
            width: 90%;
            height: 100%;
            margin: 0 auto
        }
    </style>
</head>
<body onLoad="drawMap();">
<h2>NFA Map</h2>
<h4 id="regular-expression" style="text-indent: 2em;"></h4>
<svg id="dag-canvas" width="100%" height="100%">
    <g/>
</svg>
<h5>Made By XFY9326. Powered By DagreD3.</h5>

<script src="js/d3.v4.min.js" charset="utf-8"></script>
<script src="js/dagre-d3.min.js" charset="utf-8"></script>

<script type="text/javascript" src="js/NFA.js" charset="utf-8"></script>
<script type="text/javascript">
    // const NFAMapJSON = ;

    document.getElementById("regular-expression").textContent = "Use Regular Expression: " + NFAMapJSON["originalRegularExpression"];

    let g = new dagreD3.graphlib.Graph({multigraph: true})
        .setGraph({
            rankdir: "LR"
        })
        .setDefaultEdgeLabel(function () {
            return {};
        });

    // noinspection JSPotentiallyInvalidConstructorUsage
    let render = new dagreD3.render();
    render.shapes().doubleCircle = function (parent, bbox, node) {
        let r1 = Math.max(bbox.width, bbox.height) / 2;
        let r2 = r1 * 4 / 5;
        let shapeSvg = parent;
        shapeSvg.insert("circle", ":first-child")
            .attr("x", -bbox.width / 2)
            .attr("y", -bbox.height / 2)
            .attr("r", r1);
        shapeSvg.insert("circle", ":nth-child(2)")
            .attr("x", -bbox.width / 2)
            .attr("y", -bbox.height / 2)
            .attr("r", r2);

        node.intersect = function (point) {
            return dagreD3.intersect.circle(node, r1, point);
        };

        return shapeSvg;
    };

    g.setNode(NFAMapJSON["startNode"], {label: NFAMapJSON["startNode"], shape: "doubleCircle"});
    g.setNode(NFAMapJSON["endNode"], {label: NFAMapJSON["endNode"], shape: "doubleCircle"});

    NFAMapJSON["normalNodeList"].forEach(normalNode => {
        g.setNode(normalNode, {label: normalNode, shape: "circle"});
    });

    NFAMapJSON["edgeList"].forEach((edge, index) => {
        g.setEdge(edge["fromNode"], edge["toNode"], {
            label: edge["symbol"],
            arrowhead: "normal",
            minlen: 2,
            curve: d3.curveBasis
        }, "edge" + index);
    });

    function drawMap() {
        // noinspection JSPotentiallyInvalidConstructorUsage
        let render = new dagreD3.render(),
            svg = d3.select("svg"),
            inner = d3.select("svg g");

        if (!g.graph().hasOwnProperty("marginx") &&
            !g.graph().hasOwnProperty("marginy")) {
            g.graph().marginx = 20;
            g.graph().marginy = 20;
        }

        inner.call(render, g);

        let xCenterOffset = (document.getElementById("dag-canvas").width.baseVal.value - g.graph().width) / 2;
        let yCenterOffset = (document.getElementById("dag-canvas").height.baseVal.value - g.graph().height) / 2;
        inner.attr("transform", "translate(" + xCenterOffset + ", " + yCenterOffset + ")");

        let zoom = d3.zoom().scaleExtent([0.5, 2]).on("zoom", function () {
            inner.attr("transform", "translate(" + (xCenterOffset + d3.event.transform.x / 2) + ", " + (yCenterOffset + d3.event.transform.y / 2) + ")scale(" + d3.event.transform.k + ")");
        });
        svg.call(zoom);
    }
</script>
</body>
</html>